<template>
  <div class="role-management page-container">
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">角色管理</h1>
        <p class="page-subtitle">管理系统角色，配置权限菜单</p>
      </div>
      <el-button type="primary" @click="showAddDialog = true" class="add-btn">
        <svg class="btn-icon" viewBox="0 0 24 24" fill="currentColor">
          <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
        </svg>
        新增角色
      </el-button>
    </div>

    <div class="content-card">
      <div class="search-section">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索角色名称"
          class="search-input"
          clearable
        >
          <template #prefix>
            <svg class="search-icon" viewBox="0 0 24 24" fill="currentColor">
              <path
                d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
              />
            </svg>
          </template>
        </el-input>
        <el-select
          v-model="searchStatus"
          placeholder="选择状态"
          clearable
          class="status-select"
        >
          <el-option label="启用" :value="1" />
          <el-option label="删除" :value="0" />
        </el-select>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </div>

      <el-table
        :data="roles"
        style="width: 100%"
        class="role-table"
        v-loading="loading"
      >
        <el-table-column type="index" label="序号" width="80" align="center" />
        <el-table-column prop="roleName" label="角色名称" width="150" />
        <el-table-column prop="roleCode" label="角色编码" width="150" />
        <el-table-column prop="isAdmin" label="是否超管" width="100">
          <template #default="scope">
            <el-tag
              :type="scope.row.isAdmin === 1 ? 'success' : 'info'"
              size="small"
            >
              {{ scope.row.isAdmin === 1 ? "是" : "否" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag
              :type="scope.row.status === 1 ? 'success' : 'danger'"
              size="small"
            >
              {{ scope.row.status === 1 ? "启用" : "删除" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="modifiedTime" label="修改时间" width="160" />
        <el-table-column prop="modifiedByName" label="修改人" width="180" />
        <el-table-column label="操作" width="300">
          <template #default="scope">
            <div class="action-buttons" v-if="scope.row.status !== 0">
              <el-button
                size="small"
                type="info"
                @click="showDetail(scope.row)"
                class="action-btn"
                >详情</el-button
              >
              <el-button
                size="small"
                type="primary"
                @click="editRole(scope.row)"
                class="action-btn"
                >编辑</el-button
              >
              <el-button
                size="small"
                type="warning"
                @click="bindMenus(scope.row)"
                class="action-btn"
                :disabled="scope.row.isAdmin === 1"
                >绑定权限</el-button
              >
              <el-button
                size="small"
                type="danger"
                @click="deleteRole(scope.row)"
                class="action-btn"
                :disabled="scope.row.isAdmin === 1"
                >删除</el-button
              >
            </div>
            <span v-else class="deleted-role-text">已删除</span>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 新增/编辑角色对话框 -->
    <el-dialog
      v-model="showAddDialog"
      :title="editingRole ? '编辑角色' : '新增角色'"
      width="500px"
    >
      <el-form
        ref="roleFormRef"
        :model="roleForm"
        :rules="roleRules"
        label-width="100px"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="角色编码" prop="roleCode">
          <el-input v-model="roleForm.roleCode" placeholder="不填则自动生成" />
        </el-form-item>
        <el-form-item label="状态" prop="status" v-if="!editingRole">
          <el-select v-model="roleForm.status" placeholder="请选择状态">
            <el-option label="启用" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showAddDialog = false">取消</el-button>
          <el-button type="primary" @click="saveRole" :loading="saving">{{
            editingRole ? "更新" : "创建"
          }}</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 绑定菜单对话框 -->
    <el-dialog
      v-model="showMenuDialog"
      title="角色权限配置"
      width="900px"
      :close-on-click-modal="false"
      :show-close="false"
      class="menu-dialog"
    >
      <div v-if="selectedRole" class="menu-binding-container">
        <!-- 角色信息卡片 -->
        <div class="role-info-card">
          <div class="role-info-header">
            <div class="role-avatar">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="24"
                height="24"
              >
                <path
                  d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                />
              </svg>
            </div>
            <div class="role-info">
              <h3 class="role-name">{{ selectedRole.roleName }}</h3>
              <p class="role-code">角色编码: {{ selectedRole.roleCode }}</p>
              <div class="role-status">
                <el-tag
                  :type="selectedRole.isAdmin === 1 ? 'success' : 'info'"
                  size="small"
                >
                  {{ selectedRole.isAdmin === 1 ? "超级管理员" : "普通角色" }}
                </el-tag>
              </div>
            </div>
          </div>
        </div>

        <!-- 权限配置区域 -->
        <div class="permission-section">
          <div class="section-header">
            <h4 class="section-title">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="16"
                height="16"
                style="margin-right: 8px"
              >
                <path
                  d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
                />
              </svg>
              菜单权限配置
            </h4>
            <div class="permission-stats">
              <div class="stat-item">
                <span class="stat-number">{{ roleMenuSelectedCount }}</span>
                <span class="stat-label">已选择</span>
              </div>
              <div class="stat-divider"></div>
              <div class="stat-item">
                <span class="stat-number">{{ roleMenuTotalCount }}</span>
                <span class="stat-label">总权限</span>
              </div>
              <div class="stat-divider"></div>
            </div>
          </div>

          <!-- 权限树 -->
          <div class="permission-tree-container">
            <el-tree
              ref="roleMenuTreeRef"
              :data="roleMenuTreeData"
              :props="{ children: 'children', label: 'menuName' }"
              show-checkbox
              node-key="id"
              default-expand-all
              :render-content="renderRoleMenuNode"
              @check="handleRoleMenuCheck"
            />
          </div>

          <!-- 操作提示 -->
          <div class="permission-tips">
            <div class="tip-item">
              <el-icon><InfoFilled /></el-icon>
              <span>勾选表示该角色拥有对应菜单的访问权限</span>
            </div>
            <div class="tip-item">
              <el-icon><Warning /></el-icon>
              <span>选择父级菜单会自动包含其所有子菜单权限</span>
            </div>
            <div class="tip-item">
              <el-icon><Check /></el-icon>
              <span
                >当前已选择 {{ roleMenuSelectedCount }} 项权限，共
                {{ roleMenuTotalCount }} 项</span
              >
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <div class="footer-left">
            <el-button
              @click="resetRoleMenuSelection"
              :disabled="roleMenuBindingSaving"
              class="reset-btn"
            >
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="14"
                height="14"
                style="margin-right: 4px"
              >
                <path
                  d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"
                />
              </svg>
              重置选择
            </el-button>
          </div>
          <div class="footer-right">
            <el-button
              @click="closeRoleMenuDialog"
              :disabled="roleMenuBindingSaving"
              >取消</el-button
            >
            <el-button
              type="primary"
              @click="saveRoleMenuBinding"
              :loading="roleMenuBindingSaving"
              class="save-btn"
            >
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="14"
                height="14"
                style="margin-right: 4px"
              >
                <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
              </svg>
              保存配置
            </el-button>
          </div>
        </div>
      </template>
    </el-dialog>

    <!-- 角色详情弹窗 -->
    <el-dialog
      v-model="showDetailDialog"
      title="角色详情"
      width="800px"
      class="detail-dialog"
    >
      <div v-if="detailLoading" class="loading-container">
        <el-icon class="loading-icon"><Loading /></el-icon>
        <p class="loading-text">加载中...</p>
      </div>
      <div v-else-if="roleDetail" class="role-detail-container">
        <!-- 角色基本信息卡片 -->
        <div class="detail-card">
          <div class="card-header">
            <div class="header-icon">
              <svg
                viewBox="0 0 24 24"
                fill="currentColor"
                width="24"
                height="24"
              >
                <path
                  d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
                />
              </svg>
            </div>
            <div class="header-content">
              <h3 class="role-title">{{ roleDetail.roleName }}</h3>
              <p class="role-subtitle">{{ roleDetail.roleCode }}</p>
            </div>
            <div class="header-status">
              <el-tag
                :type="roleDetail.isAdmin === 1 ? 'success' : 'info'"
                size="large"
              >
                {{ roleDetail.isAdmin === 1 ? "超级管理员" : "普通角色" }}
              </el-tag>
            </div>
          </div>
        </div>

        <!-- 基本信息 -->
        <div class="detail-section">
          <h4 class="section-title">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="16"
              height="16"
              style="margin-right: 8px"
            >
              <path
                d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
              />
            </svg>
            基本信息
          </h4>
          <div class="info-grid">
            <div class="info-item">
              <span class="info-label">角色ID</span>
              <span class="info-value">{{ roleDetail.id }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">角色编码</span>
              <span class="info-value code-value">{{
                roleDetail.roleCode
              }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">角色名称</span>
              <span class="info-value">{{ roleDetail.roleName }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">角色状态</span>
              <span class="info-value">
                <el-tag
                  :type="roleDetail.status === 1 ? 'success' : 'danger'"
                  size="small"
                >
                  {{ roleDetail.status === 1 ? "启用" : "禁用" }}
                </el-tag>
              </span>
            </div>
            <div class="info-item">
              <span class="info-label">创建时间</span>
              <span class="info-value">{{ roleDetail.createdTime }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">创建人</span>
              <span class="info-value">{{ roleDetail.createdByName }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">修改时间</span>
              <span class="info-value">{{ roleDetail.modifiedTime }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">修改人</span>
              <span class="info-value">{{ roleDetail.modifiedByName }}</span>
            </div>
          </div>
        </div>

        <!-- 菜单权限 -->
        <div
          class="detail-section"
          v-if="roleDetail.menus && roleDetail.menus.length > 0"
        >
          <h4 class="section-title">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="16"
              height="16"
              style="margin-right: 8px"
            >
              <path
                d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"
              />
            </svg>
            菜单权限 ({{ getMenuCount(roleDetail.menus) }})
          </h4>
          <div class="menu-tree-container">
            <el-tree
              :data="roleDetail.menus"
              :props="{ label: 'menuName', children: 'children' }"
              node-key="id"
              default-expand-all
              :render-content="renderMenuNode"
              class="permission-tree"
            />
          </div>
        </div>
        <div v-else class="detail-section">
          <h4 class="section-title">
            <svg
              viewBox="0 0 24 24"
              fill="currentColor"
              width="16"
              height="16"
              style="margin-right: 8px"
            >
              <path
                d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"
              />
            </svg>
            菜单权限
          </h4>
          <div class="empty-state">
            <el-empty description="暂无菜单权限" :image-size="80" />
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Loading, InfoFilled, Warning, Check } from "@element-plus/icons-vue";
import { postWithAuth } from "@/utils/request";

interface Role {
  id: string;
  roleCode: string;
  roleName: string;
  isAdmin: number;
  status: number;
  createdTime: string;
  createdBy: string;
  createdByName: string;
  modifiedTime: string;
  modifiedBy: string;
  modifiedByName: string;
}

// 响应式数据
const loading = ref(false);
const saving = ref(false);
const showAddDialog = ref(false);
const showMenuDialog = ref(false);
const showDetailDialog = ref(false);
const detailLoading = ref(false);

const editingRole = ref<Role | null>(null);
const selectedRole = ref<Role | null>(null);
const roleDetail = ref<any>(null);

const searchKeyword = ref("");
const searchStatus = ref<number | null>(null);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);

const roles = ref<Role[]>([]);

// 角色菜单相关独立变量
const roleMenuTreeData = ref<any[]>([]);
const roleMenuSelectedIds = ref<string[]>([]);
const roleMenuBindingSaving = ref(false);
const roleMenuTreeRef = ref();

// 表单数据
const roleForm = reactive({
  roleName: "",
  roleCode: "",
  status: 1,
});

// 表单验证规则
const roleRules = {
  roleName: [
    { required: true, message: "请输入角色名称", trigger: "blur" },
    { min: 2, max: 20, message: "长度在 2 到 20 个字符", trigger: "blur" },
  ],
  roleCode: [
    { max: 50, message: "角色编码长度不能超过50个字符", trigger: "blur" },
  ],
};

// 表单引用
const roleFormRef = ref();

// 角色菜单相关计算属性
const roleMenuTotalCount = computed(() => {
  const countNodes = (nodes: any[]): number => {
    return nodes.reduce((count, node) => {
      return count + 1 + (node.children ? countNodes(node.children) : 0);
    }, 0);
  };
  return countNodes(roleMenuTreeData.value);
});

const roleMenuSelectedCount = computed(() => {
  return roleMenuSelectedIds.value.length;
});

// 获取角色列表
const fetchRoles = async () => {
  loading.value = true;
  try {
    const params: any = {
      roleName: searchKeyword.value,
      pageIndex: currentPage.value,
      pageSize: pageSize.value,
    };

    if (searchStatus.value !== null) {
      params.status = searchStatus.value;
    }

    const res = await postWithAuth(
      "/internal/system/manager/getSysRolePage",
      params
    );
    if (res.code === 0 && res.data) {
      roles.value = res.data.list;
      total.value = Number(res.data.total);
    } else {
      ElMessage.error(res.message || "获取角色列表失败");
    }
  } catch (error) {
    console.error("获取角色列表失败:", error);
    ElMessage.error("获取角色列表失败");
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = () => {
  currentPage.value = 1;
  fetchRoles();
};

// 重置搜索
const resetSearch = () => {
  searchKeyword.value = "";
  searchStatus.value = null;
  currentPage.value = 1;
  fetchRoles();
};

// 分页处理
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  currentPage.value = 1;
  fetchRoles();
};

const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  fetchRoles();
};

// 编辑角色
const editRole = (role: Role) => {
  editingRole.value = role;
  Object.assign(roleForm, {
    roleName: role.roleName,
    roleCode: role.roleCode,
    status: role.status,
  });
  showAddDialog.value = true;
};

// 保存角色
const saveRole = async () => {
  if (!roleFormRef.value) return;

  try {
    await roleFormRef.value.validate();
    saving.value = true;

    if (editingRole.value) {
      // 编辑角色
      const res = await postWithAuth("/internal/system/manager/modifySysRole", {
        id: editingRole.value.id,
        roleName: roleForm.roleName,
        roleCode: roleForm.roleCode,
      });
      if (res.code === 0) {
        ElMessage.success("角色更新成功");
        showAddDialog.value = false;
        fetchRoles();
        resetForm();
      } else {
        ElMessage.error(res.message || "更新失败");
      }
    } else {
      // 新增角色
      const res = await postWithAuth("/internal/system/manager/addSysRole", {
        roleName: roleForm.roleName,
        roleCode: roleForm.roleCode,
      });
      if (res.code === 0) {
        ElMessage.success("角色创建成功");
        showAddDialog.value = false;
        fetchRoles();
        resetForm();
      } else {
        ElMessage.error(res.message || "创建失败");
      }
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  } finally {
    saving.value = false;
  }
};

// 删除角色
const deleteRole = async (role: Role) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除角色 "${role.roleName}" 吗？`,
      "确认删除",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }
    );

    const response = await postWithAuth(
      "/internal/system/manager/deleteSysRole",
      {
        id: role.id,
      }
    );

    if (response.code === 0) {
      ElMessage.success("角色删除成功");
      fetchRoles();
    } else {
      ElMessage.error(response.message || "角色删除失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      console.error("删除角色失败:", error);
      ElMessage.error("删除角色失败");
    }
  }
};

// 绑定菜单
const bindMenus = async (role: Role) => {
  selectedRole.value = role;
  showMenuDialog.value = true;
  roleMenuTreeData.value = [];
  roleMenuSelectedIds.value = [];

  try {
    const res = await postWithAuth("/internal/system/manager/menusWithRole", {
      id: role.id,
    });

    if (res.code === 0 && Array.isArray(res.data)) {
      roleMenuTreeData.value = res.data;

      // 根据选中状态回写规则处理菜单数据
      const processedData = processRoleMenuSelection(res.data);

      // 收集所有selected为true的节点ID（包括叶子节点和全选中的父节点）
      const collectSelectedIds = (nodes: any[]): string[] => {
        let ids: string[] = [];
        nodes.forEach((node) => {
          if (node.selected === true) {
            ids.push(node.id);
          }
          if (node.children && node.children.length > 0) {
            const childIds = collectSelectedIds(node.children);
            ids = ids.concat(childIds);
          }
        });
        return ids;
      };

      const selectedIds = collectSelectedIds(processedData);
      roleMenuSelectedIds.value = selectedIds;

      // 设置树形控件的选中状态
      if (roleMenuTreeRef.value) {
        roleMenuTreeRef.value.setCheckedKeys(selectedIds);
      }
    } else {
      ElMessage.error(res.message || "获取菜单失败");
      showMenuDialog.value = false;
    }
  } catch (error) {
    console.error("获取菜单失败:", error);
    ElMessage.error("获取菜单失败");
    showMenuDialog.value = false;
  }
};

// 根据选中状态回写规则处理菜单数据
const processRoleMenuSelection = (menuData: any[]): any[] => {
  // 递归处理菜单节点，返回处理后的数据
  const processNode = (node: any): any => {
    const processedNode = { ...node };

    if (!node.children || node.children.length === 0) {
      // 叶子菜单：保持原有的selected状态
      return processedNode;
    } else {
      // 父菜单：递归处理子菜单
      processedNode.children = node.children.map(processNode);

      // 计算父菜单的选中状态
      const childSelectedCount = processedNode.children.filter(
        (child: any) => child.selected === true
      ).length;
      const totalChildren = processedNode.children.length;

      if (childSelectedCount === totalChildren) {
        // 情况一：全选中状态 - 所有子菜单都选中
        processedNode.selected = true;
      } else if (childSelectedCount > 0) {
        // 情况二：部分选中状态（半选中）- 部分子菜单选中
        processedNode.selected = false;
      } else {
        // 情况三：未选中状态 - 所有子菜单都未选中
        processedNode.selected = false;
      }

      return processedNode;
    }
  };

  return menuData.map(processNode);
};

// 保存菜单绑定
const saveRoleMenuBinding = async () => {
  if (!selectedRole.value || !roleMenuTreeRef.value) return;

  roleMenuBindingSaving.value = true;
  try {
    const checkedKeys = roleMenuTreeRef.value.getCheckedKeys();

    // 根据菜单选中状态回写规则处理数据
    const processedMenuData = processRoleMenuDataForSave(checkedKeys);

    const res = await postWithAuth("/internal/system/manager/addMenusToRole", {
      roleId: selectedRole.value.id,
      menuIds: processedMenuData,
    });

    if (res.code === 0) {
      ElMessage.success("菜单绑定成功");
      showMenuDialog.value = false;
      fetchRoles();
    } else {
      ElMessage.error(res.message || "菜单绑定失败");
    }
  } catch (error) {
    console.error("菜单绑定失败:", error);
    ElMessage.error("菜单绑定失败");
  } finally {
    roleMenuBindingSaving.value = false;
  }
};

// 重置表单
const resetForm = () => {
  editingRole.value = null;
  Object.assign(roleForm, {
    roleName: "",
    roleCode: "",
    status: 1,
  });
  if (roleFormRef.value) {
    roleFormRef.value.resetFields();
  }
};

// 查看详情
const showDetail = async (row: Role) => {
  showDetailDialog.value = true;
  detailLoading.value = true;

  try {
    const res = await postWithAuth("/internal/system/manager/getSysRoleById", {
      id: row.id,
    });

    if (res.code === 0 && res.data) {
      roleDetail.value = res.data;
    } else {
      ElMessage.error(res.message || "获取详情失败");
      showDetailDialog.value = false;
    }
  } catch (error) {
    console.error("获取详情失败:", error);
    ElMessage.error("获取详情失败");
    showDetailDialog.value = false;
  } finally {
    detailLoading.value = false;
  }
};

// 处理角色菜单选择变化
const handleRoleMenuCheck = (checkedInfo: any) => {
  // 更新选中的菜单ID列表
  roleMenuSelectedIds.value = checkedInfo.checkedKeys;

  console.log("选中的菜单:", checkedInfo.checkedKeys);
  console.log("半选中的菜单:", checkedInfo.halfCheckedKeys);
};

// 重置角色菜单选择
const resetRoleMenuSelection = () => {
  if (roleMenuTreeRef.value) {
    roleMenuTreeRef.value.setCheckedKeys([]);
    roleMenuSelectedIds.value = [];
  }
};

// 关闭角色菜单对话框
const closeRoleMenuDialog = () => {
  if (roleMenuBindingSaving.value) {
    return;
  }
  showMenuDialog.value = false;
};

// 根据菜单选中状态回写规则处理角色菜单保存数据
const processRoleMenuDataForSave = (checkedKeys: string[]): any[] => {
  // 创建菜单数据副本用于处理
  const menuDataCopy = JSON.parse(JSON.stringify(roleMenuTreeData.value));

  // 递归处理菜单节点，应用选中状态回写规则
  const processNode = (node: any): any => {
    const processedNode = { ...node };

    if (!node.children || node.children.length === 0) {
      // 叶子菜单选中规则
      // 当叶子菜单本身被直接选中时，其 selected 属性必须设置为 true
      // 当叶子菜单未被选中时，其 selected 属性必须设置为 false
      processedNode.selected = checkedKeys.includes(node.id);
      return processedNode;
    } else {
      // 父菜单：递归处理子菜单
      processedNode.children = node.children.map(processNode);

      // 父菜单选中状态计算规则（递归计算）
      const childSelectedCount = processedNode.children.filter(
        (child: any) => child.selected === true
      ).length;
      const totalChildren = processedNode.children.length;

      if (childSelectedCount === totalChildren) {
        // 情况一：全选中状态 - 所有子菜单都选中
        processedNode.selected = true;
      } else if (childSelectedCount > 0) {
        // 情况二：部分选中状态（半选中）- 部分子菜单选中
        processedNode.selected = false;
      } else {
        // 情况三：未选中状态 - 所有子菜单都未选中
        processedNode.selected = false;
      }

      return processedNode;
    }
  };

  // 处理所有菜单节点
  const processedData = menuDataCopy.map(processNode);

  // 收集所有selected为true的节点ID
  const collectSelectedIds = (nodes: any[]): string[] => {
    let ids: string[] = [];
    nodes.forEach((node) => {
      if (node.selected === true) {
        ids.push(node.id);
      }
      if (node.children && node.children.length > 0) {
        const childIds = collectSelectedIds(node.children);
        ids = ids.concat(childIds);
      }
    });
    return ids;
  };

  const selectedIds = collectSelectedIds(processedData);
  console.log("处理后的选中菜单ID:", selectedIds);

  return selectedIds;
};

// 自定义角色菜单树节点渲染
const renderRoleMenuNode = (h: any, { data }: any) => {
  let tagType = "info";
  let tagLabel = "";

  if (data.menuType === 1) {
    tagType = "primary";
    tagLabel = "目录";
  } else if (data.menuType === 2) {
    tagType = "success";
    tagLabel = "菜单";
  } else if (data.menuType === 3) {
    tagType = "warning";
    tagLabel = "按钮";
  }

  return h("span", [
    h("span", data.menuName),
    h(
      "el-tag",
      {
        style: { marginLeft: "8px", fontSize: "12px", padding: "2px 8px" },
        props: { size: "small", type: tagType },
      },
      tagLabel
    ),
  ]);
};

// 自定义树节点渲染
const renderMenuNode = (h: any, { data }: any) => {
  let tagType = "info";
  let tagLabel = "";

  if (data.menuType === 1) {
    tagType = "primary";
    tagLabel = "目录";
  } else if (data.menuType === 2) {
    tagType = "success";
    tagLabel = "菜单";
  } else if (data.menuType === 3) {
    tagType = "warning";
    tagLabel = "按钮";
  }

  return h("span", [
    h("span", data.menuName),
    h(
      "el-tag",
      {
        style: { marginLeft: "8px", fontSize: "12px", padding: "2px 8px" },
        props: { size: "small", type: tagType },
      },
      tagLabel
    ),
  ]);
};

// 计算菜单数量
const getMenuCount = (menus: any[]): number => {
  const countNodes = (nodes: any[]): number => {
    return nodes.reduce((count, node) => {
      return count + 1 + (node.children ? countNodes(node.children) : 0);
    }, 0);
  };
  return countNodes(menus);
};

// 监听弹窗关闭，确保数据清理
watch(showMenuDialog, (newVal) => {
  if (!newVal) {
    // 弹窗关闭时清理数据
    roleMenuSelectedIds.value = [];
    selectedRole.value = null;
    roleMenuTreeData.value = [];
  }
});

// 页面加载时获取数据
onMounted(() => {
  fetchRoles();
});
</script>

<style scoped>
.role-management {
  padding: 24px;
  background: #f5f7fa;
  min-height: 100vh;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.header-content {
  flex: 1;
}

.page-title {
  font-size: 28px;
  font-weight: 700;
  color: #2d3748;
  margin: 0 0 8px 0;
}

.page-subtitle {
  color: #718096;
  margin: 0;
  font-size: 16px;
}

.add-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: 600;
}

.btn-icon {
  width: 16px;
  height: 16px;
}

.content-card {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.search-section {
  display: flex;
  gap: 16px;
  margin-bottom: 24px;
  align-items: center;
}

.search-input {
  flex: 1;
  max-width: 300px;
}

.status-select {
  width: 120px;
}

.search-icon {
  width: 16px;
  height: 16px;
  color: #a0aec0;
}

.role-table {
  margin-bottom: 24px;
}

.deleted-role-text {
  color: #a0aec0;
  font-size: 12px;
  font-style: italic;
}

.action-btn {
  margin-right: 8px;
}

.action-btn:last-child {
  margin-right: 0;
}

.pagination-wrapper {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

.menu-dialog {
  border-radius: 12px;
}

.menu-binding-container {
  padding: 0;
}

.role-info-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 24px;
  color: white;
}

.role-info-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.role-avatar {
  width: 48px;
  height: 48px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.role-info {
  flex: 1;
}

.role-name {
  margin: 0 0 4px 0;
  font-size: 20px;
  font-weight: 600;
  color: white;
}

.role-code {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.8);
}

.role-status {
  margin-top: 8px;
}

.permission-section {
  background: white;
  border-radius: 12px;
  border: 1px solid #e2e8f0;
  overflow: hidden;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  background: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
}

.section-title {
  margin: 0;
  color: #2d3748;
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
}

.permission-stats {
  display: flex;
  align-items: center;
  gap: 16px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.stat-number {
  font-size: 18px;
  font-weight: 700;
  color: #667eea;
}

.stat-percentage {
  font-size: 18px;
  font-weight: 700;
  color: #10b981;
}

.stat-label {
  font-size: 12px;
  color: #718096;
}

.stat-divider {
  width: 1px;
  height: 24px;
  background: #e2e8f0;
}

.permission-tree-container {
  padding: 24px;
  max-height: 400px;
  overflow-y: auto;
}

.permission-tips {
  padding: 16px 24px;
  background: #f7fafc;
  border-top: 1px solid #e2e8f0;
}

.tip-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 13px;
  color: #718096;
}

.tip-item:last-child {
  margin-bottom: 0;
}

.tip-item .el-icon {
  color: #667eea;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 0 0 0;
  border-top: 1px solid #e2e8f0;
  margin-top: 24px;
}

.footer-left,
.footer-right {
  display: flex;
  gap: 12px;
}

.reset-btn {
  color: #f59e0b;
  border-color: #f59e0b;
}

.reset-btn:hover {
  background: #f59e0b;
  color: white;
}

.save-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
}

.save-btn:hover {
  background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%);
}

/* 角色详情弹窗样式 */
.detail-dialog {
  border-radius: 12px;
}

.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
}

.loading-icon {
  font-size: 32px;
  color: #667eea;
  margin-bottom: 16px;
}

.loading-text {
  color: #718096;
  font-size: 14px;
  margin: 0;
}

.role-detail-container {
  padding: 0;
}

.detail-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 24px;
  color: white;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.header-icon {
  width: 48px;
  height: 48px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
}

.header-content {
  flex: 1;
}

.role-title {
  margin: 0 0 4px 0;
  font-size: 24px;
  font-weight: 700;
  color: white;
}

.role-subtitle {
  margin: 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.8);
}

.header-status {
  margin-left: auto;
}

.detail-section {
  background: white;
  border-radius: 12px;
  border: 1px solid #e2e8f0;
  overflow: hidden;
  margin-bottom: 20px;
}

.section-title {
  margin: 0;
  color: #2d3748;
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
  padding: 20px 24px;
  background: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  padding: 24px;
}

.info-item {
  display: flex;
  align-items: center;
  padding: 16px;
  background: #f7fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.info-label {
  font-weight: 600;
  color: #4a5568;
  min-width: 80px;
  margin-right: 16px;
  font-size: 14px;
}

.info-value {
  color: #2d3748;
  flex: 1;
  font-size: 14px;
}

.code-value {
  font-family: "Courier New", monospace;
  background: #edf2f7;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 13px;
}

.menu-tree-container {
  padding: 24px;
  max-height: 400px;
  overflow-y: auto;
}

.permission-tree {
  border: none;
}

.empty-state {
  padding: 40px 24px;
  text-align: center;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .detail-dialog {
    width: 95% !important;
    max-width: 600px;
  }

  .detail-card {
    padding: 20px;
    margin-bottom: 20px;
  }

  .card-header {
    gap: 12px;
  }

  .header-icon {
    width: 40px;
    height: 40px;
  }

  .role-title {
    font-size: 20px;
  }

  .role-subtitle {
    font-size: 13px;
  }

  .section-title {
    padding: 16px 20px;
    font-size: 14px;
  }

  .info-grid {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 20px;
  }

  .info-item {
    padding: 12px;
  }

  .info-label {
    min-width: 70px;
    font-size: 13px;
  }

  .info-value {
    font-size: 13px;
  }

  .menu-tree-container {
    padding: 20px;
    max-height: 300px;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .role-management {
    padding: 16px;
  }

  .page-header {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }

  .page-title {
    font-size: 20px;
  }

  .page-subtitle {
    font-size: 14px;
  }

  .add-btn {
    align-self: flex-start;
  }

  .content-card {
    padding: 16px;
  }

  .search-section {
    flex-direction: column;
    align-items: stretch;
  }

  .search-input {
    max-width: none;
  }

  .action-btn {
    margin-right: 4px;
    margin-bottom: 4px;
  }

  .menu-tree-container {
    max-height: 300px;
  }

  .dialog-footer {
    flex-direction: column;
    gap: 12px;
  }

  .role-info-card {
    padding: 20px;
    margin-bottom: 20px;
  }

  .role-info-header {
    gap: 12px;
  }

  .role-avatar {
    width: 40px;
    height: 40px;
  }

  .role-name {
    font-size: 18px;
  }

  .role-code {
    font-size: 13px;
  }

  .section-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }

  .permission-stats {
    gap: 12px;
  }

  .permission-tree-container {
    padding: 20px;
    max-height: 300px;
  }

  .permission-tips {
    padding: 12px 20px;
  }

  .tip-item {
    font-size: 12px;
  }

  .footer-left,
  .footer-right {
    width: 100%;
    justify-content: center;
  }
}
</style>
